#ifndef ODBC_PARAMETER_HPP
#define ODBC_PARAMETER_HPP

#include "odbc/details/parameter_buffer.hpp"

namespace odbc
{

class statement;

/// \ingroup OdbcLibrary
/// \brief 
///		It describes a parameter to be bound to an ODBC statement.
/// \details
///		It owns a buffer that is actually bound to the statement.
///		\n
///		The parameter can't be created directly, but through the methods of the statement.
///		\n
///		One can get and set the value of the parameter, but she can't change other parameter properties, like direction.
class ODBC_DECL parameter: public boost::noncopyable
{
public:
	///	\brief
	///		It enumerates the possible parameter directions.
	enum e_direction
	{
		in = SQL_PARAM_INPUT,				///< It indicates an input parameter.
		inout = SQL_PARAM_INPUT_OUTPUT,		///< It indicates and input/output parameter.
		out = SQL_PARAM_OUTPUT				///< It indicates an output parameter.
	};

private:
	friend class statement;

	/// \brief It initializes the parameter.
	/// \param p_buffer the buffer bound to the statement.
	/// \details
	///		It takes the ownership of the buffer.
	/// \pre
	///		The provided buffer is not null.
	/// \pre 
	///		The provided buffer is a parameter buffer.
	/// \pre
	///		The provided buffer is already bound to the statement.
	explicit parameter( details::bindable_buffer_base* p_buffer);

public:
	/// \brief It destroys the bound buffer.
	~parameter() { delete p_bound_buffer_; }

	/// \brief It gets the direction of the parameter.
	e_direction direction() const { return direction_; }

	///	\brief
	///		It gets the value existing in the buffer, or an empty value if a null value exists in the buffer.
	///	\return the value in the buffer.
	boost::any value() const;

	/// \brief
	///		It sets the value of the parameter.
	/// \details
	///		If the parameter is an output parameter, the set value is ignored.
	/// \param val
	///		the new value of the parameter. If this is an empty <tt>boost::any</tt> value, the parameter value is 
	///		considered to be \c NULL.
	/// \exception boost::bad_any_cast
	///		Thrown if the specified value is not convertible to the C++ type of this parameter.
	void set_value( const boost::any& val);

private:
	/// \internal
	/// \brief It contains the buffer bound to the statement.
	details::bindable_buffer_base* p_bound_buffer_;

	/// \internal
	/// \brief It holds the direction of the parameter.
	e_direction direction_;
};

} // namespace odbc

#endif // ODBC_PARAMETER_HPP
